package com.jiwang.mail.service.impl;

import com.jiwang.mail.dto.QueryMailInfo;
import com.jiwang.mail.dto.SendMailInfo;
import com.jiwang.mail.service.MailService;
import com.jiwang.mail.util.mail.MailUtil;
import com.jiwang.mail.util.result.JsonResult;
import com.jiwang.mail.util.result.ResultFactory;
import com.jiwang.mail.util.result.ResultStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.MailException;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.mail.Folder;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Store;
import java.io.UnsupportedEncodingException;

/**
 * @author 沈伟峰
 */
@Service
public class MailServiceImpl implements MailService {

    @Autowired
    private JavaMailSenderImpl mailSender;
    private JsonResult result;

    @Override
    public JsonResult sendMail(SendMailInfo info) {
        result = ResultFactory.newSuccessJsonResult();

        // 合法性检验
        if (!MailUtil.checkMail(info))
            return result.setStatus(ResultStatus.MAIL_MISS_INFO);

        // 填充缺省信息
        MailUtil.fixDefault(info);
        // 更新 sender 信息
        updateMailSender(info);

        // 分别处理
        if (MailUtil.isSimpleMail(info)) {
            sendSimpleMail(info);
        } else {
            sendMimeMail(info);
        }

        return result;
    }

    @Override
    public JsonResult queryMails(QueryMailInfo info) {
        result = ResultFactory.newSuccessJsonResult();

        Session session = MailUtil.createSession(info);
        Store store;
        try {
            store = session.getStore(info.getProtocol());
            store.connect(info.getUsername(), info.getPassword());
            Folder folder = store.getFolder("INBOX");
            folder.open(Folder.READ_WRITE);
        } catch (MessagingException e) {
            e.printStackTrace();
            return result.setStatus(ResultStatus.MAIL_SESSION_FAIL);
        }

        return result;
    }

    /**
     * 发送简单邮件
     *
     * @param info 邮件信息
     */
    private void sendSimpleMail(SendMailInfo info) {
        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom(info.getFrom());
        message.setTo(info.getTo());
        message.setSubject(info.getSubject());
        message.setText(info.getText());
        message.setSentDate(info.getDate());
        message.setCc(info.getCc());
        message.setBcc(info.getBcc());
        message.setReplyTo(info.getReplyTo());
        try {
            mailSender.send(message);
        } catch (MailException e) {
            result.setStatus(ResultStatus.MAIL_SEND_FAIL);
        }
    }

    /**
     * 发送复杂邮件
     *
     * @param info 邮件信息
     */
    private void sendMimeMail(SendMailInfo info) {
        MimeMessageHelper helper;
        try {
            helper = new MimeMessageHelper(mailSender.createMimeMessage(), true);
            helper.setFrom(info.getFrom());
            helper.setTo(info.getTo());
            helper.setSubject(info.getSubject());
            helper.setText(info.getText(), info.isHtml());
            if (ObjectUtils.isEmpty(info.getPersonal())) {
                helper.setReplyTo(info.getReplyTo());
            } else {
                helper.setReplyTo(info.getReplyTo(), info.getPersonal());
            }
            helper.setSentDate(info.getDate());
            helper.setCc(info.getCc());
            helper.setBcc(info.getBcc());
            for (MultipartFile f : info.getFiles()) {
                String name = f.getOriginalFilename();
                if (name == null) name = f.getName();
                helper.addAttachment(name, f);
            }
        } catch (MessagingException | UnsupportedEncodingException e) {
            result.setStatus(ResultStatus.MAIL_PARSE_FAIL);
            return;
        }
        try {
            mailSender.send(helper.getMimeMessage());
        } catch (MailException e) {
            result.setStatus(ResultStatus.MAIL_SEND_FAIL);
        }
    }

    private void updateMailSender(SendMailInfo info) {
        mailSender = new JavaMailSenderImpl();
        mailSender.setHost(info.getHost());
        mailSender.setPort(info.getPort());
        mailSender.setUsername(info.getFrom());
        mailSender.setPassword(info.getPassword());
        mailSender.setDefaultEncoding(info.getEncoding());
        mailSender.setProtocol(info.getProtocol());
    }

}
